# -*- coding: utf-8 -*-

# -------------------------------
# Author    : linlingwei
# Email     : 951035650@qq.com
# File Name : fStretch.py
# Date      : 2019/9/19 
# IDE       : PyCharm
# Version   : 1.0.1
# -------------------------------

import traceback

import maya.cmds as mc
import maya.mel as mel

import configs.constants.facial_constant as fc
import configs.constants.global_constant as gc
import configs.constants.suffix_constant as sc
import configs.constants.nodeType_constant as ntc
import configs.constants.attribute_constant as ac

import scripts.commonCmds as con
reload(con)
import scripts.curveCmds as cr
import scripts.deformerCmds as dc
reload(dc)
import rig.facial.fCore as fCore
reload(fCore)

class Stretch(fCore.FacialCore):
    def __init__(self):
        super(Stretch,self).__init__(fc.stretch)
        self.transform_init()
    def create(self):
        try:
            self.upStretch_driver()
            # self.control()
            self.hide_doDelete()
        except:
            traceback.print_exc()
        
        return
    
    def upStretch_driver(self):
        
        lname = con.lname(fc.stretch,fc.up)
        # lgrp = mc.createNode(ntc.tTransform,name = con.lname(lname,sc.sGrp),parent=self.local_static)
        sh_tmp_root = con.lname(fc.stretch,fc.up,fc.root)
        sh_tmp_jl1 = con.lname(fc.stretch,fc.up,1)
        sh_tmp_jl2 = con.lname(fc.stretch, fc.up, 2)
        tmp_list = [sh_tmp_root,sh_tmp_jl1,sh_tmp_jl2]
        # self.stretch_spline(sh_tmp_jl1,sh_tmp_root,con.lname(lname,1))
        # self.stretch_spline(sh_tmp_jl1, sh_tmp_jl2, con.lname(lname, 2))
        self.jot_stretch(tmp_list,lname)
        return
    
    def stretch_spline(self,sobj,eobj,name):
        
        lgrp = mc.createNode(ntc.tTransform,name=con.lname(name,sc.sGrp),parent=self.local_static)
        
        pts = list()
        loc_list = list()
        for i,_obj in enumerate([sobj,eobj]):
            loc = mc.spaceLocator(name = con.lname(name,i+1,sc.sLoc))[0]
            mc.parent(loc,lgrp)
            mc.hide(loc)
            loc_list.append(loc)
            mc.delete(mc.parentConstraint(_obj,loc,mo=False))
            pt = mc.xform(_obj,q=True,ws=True,t=True)
            pts.append(pt)
            con.emptyGroup(loc)
        
        vec = lambda a,b:((b[0]-a[0])/2.,(b[1]-a[1])/2.,(b[2]-a[2])/2.)
        pt_vec = vec(pts[0],pts[1])
        pt_mid = pt_vec[0]+pts[0][0],pt_vec[1]+pts[0][1],pt_vec[2]+pts[0][2]
        
        crv_pts = [pts[0],pt_mid,pts[1]]
        crv = mc.rename(mc.curve(p=crv_pts,d=2),con.lname(name,sc.sCrv))
        crvShape = con.findRelatedShape(crv)
        
        clu_list = list()
        for cv in mc.ls(crv+".cv[*]",fl=True):
            clu = mc.rename(mc.cluster(cv)[1],con.lname(name,"cluster"))
            mc.hide(clu)
            clu_list.append(clu)
        mc.parent(clu_list[0],loc_list[0])
        mc.parent(clu_list[1],lgrp)
        mc.parent(clu_list[2],loc_list[1])

        crv_info = mc.createNode(ntc.tCurveInfo,name= con.lname(crv,sc.sCi))
        mc.connectAttr(crvShape+".ws",crv_info+".ic")
        
        mdl = mc.createNode(ntc.tMultDoubleLinear,name=con.lname(name,sc.sMdl))
        mc.connectAttr(crv_info+".al",mdl+".i1")
        mc.setAttr(mdl+".i2",1./mc.getAttr(crv_info+".al"))
        
        mc.addAttr(lgrp,ln=fc.stretch,at="float",k=True)
        mc.connectAttr(mdl+".o",con.lAttr(lgrp,fc.stretch))
        
        jot_list= list()
        pat = None
        pt_mid = pt_vec[0]+pts[0][0],pt_vec[1]+pts[0][1],pt_vec[2]+pts[0][2]
        for i,pt in enumerate([pts[0],pt_mid,pts[1]]):
            jot = mc.createNode(ntc.tJoint,name= con.lname(name,i,sc.sJot))
            mc.setAttr(jot + ".t",pt[0],pt[1],pt[2])
            mc.setAttr(jot+".radius",0.05)
            jot_list.append(jot)
            if pat:
                mc.parent(jot,pat)
            pat = jot
        mc.sets(jot_list,include=self.local_sets)
        con.jointOrient(jot_list)
        ikh = mc.ikHandle(sj=jot_list[0],ee=jot_list[-1],sol = "ikSplineSolver",c=crv,roc=True,ccv=False,
                          name = con.lname(name,sc.sIkhandle))[0]
        mc.hide(ikh)
        mc.parent(crv,jot_list[0],ikh,lgrp)
        for i in range(len(jot_list)):
            if i+1 > len(jot_list)-1:
                continue
            dis1 = mc.createNode(ntc.tDistanceBetween,name = con.lname(name,sc.sDbn))

            pt1_poci = mc.createNode(ntc.tPointOnCurveInfo,name = con.lname(name,sc.sPoci))
            mc.connectAttr(crvShape+".ws",pt1_poci+".ic")
            par = con.getObjInCrvParameter(crv,jot_list[i])
            mc.setAttr(pt1_poci+".top",1)
            mc.setAttr(pt1_poci+".pr",par)
            mc.connectAttr(pt1_poci+".p",dis1+".p1")

            pt1_poci = mc.createNode(ntc.tPointOnCurveInfo,name = con.lname(name,sc.sPoci))
            mc.connectAttr(crvShape+".ws",pt1_poci+".ic")
            par = con.getObjInCrvParameter(crv,jot_list[i+1])
            mc.setAttr(pt1_poci+".top",1)
            mc.setAttr(pt1_poci+".pr",par)
            mc.connectAttr(pt1_poci+".p",dis1+".p2")

            mc.connectAttr(dis1+".d",jot_list[i+1]+".tx")
            
            dr = con.lAttr(lgrp,fc.stretch)
            for _at in ["sy","sz"]:
                dn = con.lAttr(jot_list[i],_at)
                mc.setDrivenKeyframe(dn,cd=dr,dv=1,v=1,itt="linear",ott="linear")
                mc.setDrivenKeyframe(dn,cd=dr,dv=2,v=0.5,itt="linear",ott="linear")
                mc.setDrivenKeyframe(dn, cd=dr, dv=0.5, v=2, itt="linear", ott="linear")
        return
    
    def control(self):
    
        sh_tmp_jl1 = con.lname(fc.stretch, fc.up, 1)
        sh_tmp_jl2 = con.lname(fc.stretch, fc.up, 2)
        
        mctr = cr.objToControl(sh_tmp_jl1,name=con.lname(fc.stretch,fc.mid),ctrlShape="cube")
        uctr = cr.objToControl(sh_tmp_jl2,name=con.lname(fc.stretch,fc.up),ctrlShape="cube")
        for _ctr in [mctr,uctr]:
            mc.parent(_ctr,self.local_toParent)
            con.emptyGroup(_ctr)
            cr.changColor(_ctr,18)
            cr.scaleXYZ(_ctr,0.2)
        
        mc.connectAttr(mctr+".t",con.lname(fc.stretch,fc.up,1,1,sc.sLoc)+".t")
        mc.connectAttr(mctr+".t",con.lname(fc.stretch,fc.up,2,1,sc.sLoc)+".t")
        
        mc.connectAttr(uctr + ".t", con.lname(fc.stretch, fc.up, 2, 2, sc.sLoc)+".t")
        return
    
    def lattice(self):
        
        
        
        return
    
    def jot_stretch(self,tmp_loc,name):
    
        lgrp = mc.createNode(ntc.tTransform, name=con.lname(name, sc.sGrp), parent=self.local_static)
    
        pts = list()
        loc_list = list()
        for i, _obj in enumerate(tmp_loc):
            loc = mc.spaceLocator(name=con.lname(name, i + 1, sc.sLoc))[0]
            mc.parent(loc, lgrp)
            mc.hide(loc)
            loc_list.append(loc)
            mc.delete(mc.parentConstraint(_obj, loc, mo=False))
            pt = mc.xform(_obj, q=True, ws=True, t=True)
            pts.append(pt)
            con.emptyGroup(loc)
        crv = mc.rename(mc.curve(p=[pts[0],pts[1],pts[1],pts[2]],d=3),con.lname(name,sc.sCrv))
        #           rebuildCurve -ch 1 -rpo 1 -rt 0 -end 1 -kr 0 -kcp 1 -kep 1 -kt 0 -s 0 -d 2 -tol 0.01 "Stretch_Up_crv";
        mel.eval('rebuildCurve -ch 0 -rpo 1 -rt 0 -end 1 -kr 0 -kcp 1 -kep 1 -kt 0 -s 0 -d 3 -tol 0.01 "%s";' % crv)
        crvShape = con.findRelatedShape(crv)
        vec = lambda a, b: [(b[0] - a[0]) / 2.+a[0], (b[1] - a[1]) / 2.+a[1], (b[2] - a[2]) / 2.+a[2]]
        pt_vec1 = vec(pts[0], pts[1])
        pt_vec2 = vec(pts[1], pts[2])
        # print pts
        # print pt_vec2
        pts_list = [pts[0],pt_vec1, pts[1], pt_vec2,pts[2]]
        jotPat = None
        poci_list = list()
        jot_list = list()
        for i,pt in enumerate(pts_list):
            jot = mc.createNode(ntc.tJoint,name=con.lname(name,i+1,sc.sJot))
            mc.setAttr(jot+".t",pt[0],pt[1],pt[2])
            par = con.getObjInCrvParameter(crv,jot)
            # print par
            poci = mc.createNode(ntc.tPointOnCurveInfo,name=con.lname(name,i+1,sc.sPoci))
            mc.connectAttr(crvShape+".ws",poci+".ic")
            mc.setAttr(poci+".top",1)
            mc.setAttr(poci+".pr",par)
            # print pt
            if jotPat:
                mc.parent(jot,jotPat)
            jotPat = jot
            poci_list.append(poci)
            jot_list.append(jot)
        con.jointOrient(jot_list)
        
        ikh = mc.ikHandle(sj=jot_list[0],ee=jot_list[-1],sol = "ikSplineSolver",c=crv,roc=True,ccv=False,
                          name = con.lname(name,sc.sIkhandle))[0]
        mc.hide(ikh)
        
        for i,po in enumerate(poci_list[:-1]):
            dis = mc.createNode(ntc.tDistanceBetween,name = con.lname(name,i,sc.sDbn))
            mc.connectAttr(po+".p",dis+".p1")
            mc.connectAttr(poci_list[i+1]+".p",dis+".p2")
            
            mc.connectAttr(dis+".d",jot_list[i+1]+".tx")
            
            md = mc.createNode(ntc.tMultiplyDivide,name = con.lname(name,i,sc.sMd))
            mc.connectAttr(dis+".d",md+".i1x")
            mc.setAttr(md+".i2x",mc.getAttr(dis+".d"))
            mc.setAttr(md+".op",2)
            
            dr = con.lAttr(md,"ox")
            for _at in ["sy","sz"]:
                dn = con.lAttr(jot_list[i],_at)
                mc.setDrivenKeyframe(dn,cd=dr,dv=1,v=1,itt="linear",ott="linear")
                mc.setDrivenKeyframe(dn,cd=dr,dv=2,v=0.5,itt="linear",ott="linear")
                mc.setDrivenKeyframe(dn, cd=dr, dv=0.5, v=2, itt="linear", ott="linear")
        for i,_loc in enumerate(loc_list):
            # print _loc
            if i == 0:
                clu = mc.cluster(crv+".cv[0]")[1]
            elif i == 1:
                clu = mc.cluster(crv + ".cv[1:2]")[1]
            elif i == 2:
                clu = mc.cluster(crv + ".cv[3]")[1]
                
            # print clu
            cgrp = con.emptyGroup(clu,["Zero"])[0]
            mc.hide(clu)
            mc.parent(cgrp,_loc)
        
        
        return
    
    
if __name__ == '__main__':
    pass